home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / board / GNUChess4_0_58.lha / gnuchess-4.0 / src / new / eval.c < prev    next >
C/C++ Source or Header  |  1992-08-26  |  33KB  |  1,340 lines

  1. /*
  2.  * eval.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include "gnuchess.h"
  24. #include "ataks.h"
  25. short int sscore[2];
  26. /* Backward pawn bonus indexed by # of attackers on the square */
  27. static const short BACKWARD[16] =
  28. {-6, -10, -15, -21, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28};
  29.  
  30. /* Bishop mobility bonus indexed by # reachable squares */
  31. static const short BMBLTY[14] =
  32. {-2, 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16, 16, 16};
  33.  
  34. /* Rook mobility bonus indexed by # reachable squares */
  35. static const short RMBLTY[15] =
  36. {0, 2, 4, 6, 8, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14};
  37.  
  38. /* Positional values for a dying king */
  39. static const short DyingKing[64] =
  40. {0, 8, 16, 24, 24, 16, 8, 0,
  41.  8, 32, 40, 48, 48, 40, 32, 8,
  42.  16, 40, 56, 64, 64, 56, 40, 16,
  43.  24, 48, 64, 72, 72, 64, 48, 24,
  44.  24, 48, 64, 72, 72, 64, 48, 24,
  45.  16, 40, 56, 64, 64, 56, 40, 16,
  46.  8, 32, 40, 48, 48, 40, 32, 8,
  47.  0, 8, 16, 24, 24, 16, 8, 0};
  48.  
  49. /* Isoloted pawn penalty by rank */
  50. static const short ISOLANI[8] =
  51. {-12, -16, -20, -24, -24, -20, -16, -12};
  52.  
  53. /* table for King Bishop Knight endings */
  54. static const short KBNK[64] =
  55. {99, 90, 80, 70, 60, 50, 40, 40,
  56.  90, 80, 60, 50, 40, 30, 20, 40,
  57.  80, 60, 40, 30, 20, 10, 30, 50,
  58.  70, 50, 30, 10, 0, 20, 40, 60,
  59.  60, 40, 20, 0, 10, 30, 50, 70,
  60.  50, 30, 10, 20, 30, 40, 60, 80,
  61.  40, 20, 30, 40, 50, 60, 80, 90,
  62.  40, 40, 50, 60, 70, 80, 90, 99};
  63.  
  64. /* penalty for threats to king, indexed by number of such threats */
  65. static const short KTHRT[36] =
  66. {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
  67.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
  68.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
  69.  
  70. /* King positional bonus inopening stage */
  71. static const short KingOpening[64] =
  72. {0, 0, -4, -10, -10, -4, 0, 0,
  73.  -4, -4, -8, -12, -12, -8, -4, -4,
  74.  -12, -16, -20, -20, -20, -20, -16, -12,
  75.  -16, -20, -24, -24, -24, -24, -20, -16,
  76.  -16, -20, -24, -24, -24, -24, -20, -16,
  77.  -12, -16, -20, -20, -20, -20, -16, -12,
  78.  -4, -4, -8, -12, -12, -8, -4, -4,
  79.  0, 0, -4, -10, -10, -4, 0, 0};
  80.  
  81. /* King positional bonus in end stage */
  82. static const short KingEnding[64] =
  83. {0, 6, 12, 18, 18, 12, 6, 0,
  84.  6, 12, 18, 24, 24, 18, 12, 6,
  85.  12, 18, 24, 30, 30, 24, 18, 12,
  86.  18, 24, 30, 36, 36, 30, 24, 18,
  87.  18, 24, 30, 36, 36, 30, 24, 18,
  88.  12, 18, 24, 30, 30, 24, 18, 12,
  89.  6, 12, 18, 24, 24, 18, 12, 6,
  90.  0, 6, 12, 18, 18, 12, 6, 0};
  91.  
  92. /* Passed pawn positional bonus */
  93. static const short PassedPawn0[8] =
  94. {0, 60, 80, 120, 200, 360, 600, 800};
  95. static const short PassedPawn1[8] =
  96. {0, 30, 40, 60, 100, 180, 300, 800};
  97. static const short PassedPawn2[8] =
  98. {0, 15, 25, 35, 50, 90, 140, 800};
  99. static const short PassedPawn3[8] =
  100. {0, 5, 10, 15, 20, 30, 140, 800};
  101.  
  102. /* Knight positional bonus */
  103. static const short pknight[64] =
  104. {0, 4, 8, 10, 10, 8, 4, 0,
  105.  4, 8, 16, 20, 20, 16, 8, 4,
  106.  8, 16, 24, 28, 28, 24, 16, 8,
  107.  10, 20, 28, 32, 32, 28, 20, 10,
  108.  10, 20, 28, 32, 32, 28, 20, 10,
  109.  8, 16, 24, 28, 28, 24, 16, 8,
  110.  4, 8, 16, 20, 20, 16, 8, 4,
  111.  0, 4, 8, 10, 10, 8, 4, 0};
  112.  
  113. /* Bishop positional bonus */
  114. static const short pbishop[64] =
  115. {14, 14, 14, 14, 14, 14, 14, 14,
  116.  14, 22, 18, 18, 18, 18, 22, 14,
  117.  14, 18, 22, 22, 22, 22, 18, 14,
  118.  14, 18, 22, 22, 22, 22, 18, 14,
  119.  14, 18, 22, 22, 22, 22, 18, 14,
  120.  14, 18, 22, 22, 22, 22, 18, 14,
  121.  14, 22, 18, 18, 18, 18, 22, 14,
  122.  14, 14, 14, 14, 14, 14, 14, 14};
  123.  
  124. /* Pawn positional bonus */
  125. static const short PawnAdvance[64] =
  126. {0, 0, 0, 0, 0, 0, 0, 0,
  127.  4, 4, 4, 0, 0, 4, 4, 4,
  128.  6, 8, 2, 10, 10, 2, 8, 6,
  129.  6, 8, 12, 16, 16, 12, 8, 6,
  130.  8, 12, 16, 24, 24, 16, 12, 8,
  131.  12, 16, 24, 32, 32, 24, 16, 12,
  132.  12, 16, 24, 32, 32, 24, 16, 12,
  133.  0, 0, 0, 0, 0, 0, 0, 0};
  134. #if !defined NOSCORESPACE
  135. #ifdef BLACKAG0
  136. /* Space positional bonus */
  137. static const short SpaceBonusB[64] =
  138. {0, 0, 0, 0, 0, 0, 0, 0,
  139.  0, 0, 2, 2, 2, 2, 0, 0,
  140.  1, 1, 2, 4, 4, 2, 1, 1,
  141.  0, 0, 3, 4, 4, 3, 0, 0,
  142.  0, 0, 5, 5, 5, 5, 0, 0,
  143.  0, 0, 4, 4, 7, 7, 0, 0,
  144.  0, 0, 0, 0, 0, 0, 0, 0,
  145.  0, 0, 0, 0, 0, 0, 0, 0};
  146. #elif defined BLACKAG1
  147. /* Space positional bonus */
  148. static const short SpaceBonusB[64] =
  149. {1, 1, 1, 1, 1, 1, 1, 1,
  150.  1, 1, 2, 2, 2, 2, 1, 1,
  151.  1, 1, 2, 3, 3, 2, 1, 1,
  152.  1, 1, 2, 4, 4, 2, 1, 1,
  153.  1, 1, 3, 5, 5, 3, 1, 1,
  154.  1, 1, 3, 6, 6, 3, 1, 1,
  155.  1, 1, 3, 7, 7, 3, 1, 1,
  156.  1, 1, 1, 1, 1, 1, 1, 1};
  157. #elif defined BLACKAG2
  158. /* Space positional bonus */
  159. static const short SpaceBonusB[64] =
  160. {1, 1, 1, 1, 1, 1, 1, 1,
  161.  1, 1, 2, 2, 2, 2, 1, 1,
  162.  1, 1, 3, 3, 3, 3, 1, 1,
  163.  1, 1, 4, 4, 4, 4, 1, 1,
  164.  1, 1, 5, 6, 6, 5, 1, 1,
  165.  1, 1, 6, 7, 7, 6, 1, 1,
  166.  1, 1, 7, 8, 8, 7, 1, 1,
  167.  1, 1, 1, 1, 1, 1, 1, 1};
  168. #elif defined BLACKAG3
  169. /* Space positional bonus */
  170. static const short SpaceBonusB[64] =
  171. {0, 0, 0, 0, 0, 0, 0, 0,
  172.  0, 0, 2, 2, 2, 2, 0, 0,
  173.  0, 0, 3, 3, 3, 3, 0, 0,
  174.  0, 0, 4, 4, 4, 3, 0, 0,
  175.  0, 0, 6, 6, 4, 4, 0, 0,
  176.  0, 0, 7, 7, 5, 5, 0, 0,
  177.  0, 0, 8, 8, 7, 7, 0, 0,
  178.  0, 0, 0, 0, 0, 0, 0, 0};
  179. #elif defined BLACKAG4
  180. /* Space positional bonus */
  181. static const short SpaceBonusB[64] =
  182. {1, 1, 1, 1, 1, 1, 1, 1,
  183.  1, 1, 2, 4, 4, 2, 1, 1,
  184.  1, 1, 2, 4, 4, 2, 1, 1,
  185.  1, 1, 2, 4, 4, 2, 1, 1,
  186.  1, 1, 2, 4, 4, 2, 1, 1,
  187.  1, 1, 2, 4, 4, 2, 1, 1,
  188.  1, 1, 2, 4, 4, 2, 1, 1,
  189.  1, 1, 1, 1, 1, 1, 1, 1};
  190. #endif
  191.  
  192. #ifdef WHITEAG0
  193. /* Space positional bonus */
  194. static const short SpaceBonusW[64] =
  195. {0, 0, 0, 0, 0, 0, 0, 0,
  196.  0, 0, 5, 5, 5, 5, 0, 0,
  197.  0, 0, 3, 4, 4, 3, 0, 0,
  198.  0, 0, 2, 4, 4, 2, 0, 0,
  199.  0, 0, 1, 4, 4, 1, 0, 0,
  200.  0, 0, 1, 4, 4, 1, 0, 0,
  201.  0, 0, 1, 2, 2, 1, 0, 0,
  202.  0, 0, 0, 0, 0, 0, 0, 0};
  203. #elif defined WHITEAG1
  204. /* Space positional bonus */
  205. static const short SpaceBonusW[64] =
  206. {1, 1, 1, 1, 1, 1, 1, 1,
  207.  1, 1, 3, 7, 7, 3, 1, 1,
  208.  1, 1, 3, 6, 6, 3, 1, 1,
  209.  1, 1, 3, 5, 5, 3, 1, 1,
  210.  1, 1, 2, 4, 4, 2, 1, 1,
  211.  1, 1, 2, 3, 3, 2, 1, 1,
  212.  1, 1, 2, 2, 2, 2, 1, 1,
  213.  1, 1, 1, 1, 1, 1, 1, 1};
  214. #elif defined WHITEAG2
  215. /* Space positional bonus */
  216. static const short SpaceBonusW[64] =
  217. {1, 1, 1, 1, 1, 1, 1, 1,
  218.  1, 1, 7, 8, 8, 7, 1, 1,
  219.  1, 1, 6, 7, 7, 6, 1, 1,
  220.  1, 1, 5, 6, 6, 5, 1, 1,
  221.  1, 1, 4, 4, 4, 4, 1, 1,
  222.  1, 1, 3, 3, 3, 3, 1, 1,
  223.  1, 1, 2, 2, 2, 2, 1, 1,
  224.  1, 1, 1, 1, 1, 1, 1, 1};
  225. #elif defined WHITEAG3
  226. /* Space positional bonus */
  227. static const short SpaceBonusW[64] =
  228. {0, 0, 0, 0, 0, 0, 0, 0,
  229.  0, 0, 8, 8, 7, 7, 0, 0,
  230.  0, 0, 7, 7, 5, 5, 0, 0,
  231.  0, 0, 6, 6, 4, 4, 0, 0,
  232.  0, 0, 4, 4, 4, 3, 0, 0,
  233.  0, 0, 3, 3, 3, 3, 0, 0,
  234.  0, 0, 2, 2, 2, 2, 0, 0,
  235.  0, 0, 0, 0, 0, 0, 0, 0};
  236. #elif defined WHITEAG4
  237. /* Space positional bonus */
  238. static const short SpaceBonusW[64] =
  239. {1, 1, 1, 1, 1, 1, 1, 1,
  240.  1, 1, 2, 4, 4, 2, 1, 1,
  241.  1, 1, 2, 4, 4, 2, 1, 1,
  242.  1, 1, 2, 4, 4, 2, 1, 1,
  243.  1, 1, 2, 4, 4, 2, 1, 1,
  244.  1, 1, 2, 4, 4, 2, 1, 1,
  245.  1, 1, 2, 4, 4, 2, 1, 1,
  246.  1, 1, 1, 1, 1, 1, 1, 1};
  247. #endif
  248. #endif
  249.  
  250. short Mwpawn[64], Mbpawn[64], Mknight[2][64], Mbishop[2][64];
  251. static short Mking[2][64], Kfield[2][64];
  252. static short c1, c2, *atk1, *atk2, *PC1, *PC2, atak[2][64];
  253. short emtl[2];
  254. static short PawnBonus, BishopBonus, RookBonus;
  255. static short KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
  256. static short PEDRNK2B, PWEAKH, PADVNCM, PADVNCI, PAWNSHIELD, PDOUBLED,
  257.  PBLOK;
  258. static short RHOPN, RHOPNX, KHOPN, KHOPNX, KSFTY;
  259. static short ATAKD, HUNGP, HUNGX, KCASTLD, KMOVD, XRAY, PINVAL;
  260. short pscore[2];
  261. short tmtl;
  262.  
  263. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  264.  
  265. /*
  266.  * Inputs are:
  267.  * pmtl[side] - value of pawns
  268.  * mtl[side]  - value of all material
  269.  * emtl[side] - vaule of all material - value of pawns - value of king
  270.  * hung[side] - count of hung pieces
  271.  * Tscore[ply] - search tree score for ply
  272.  * ply
  273.  * Pscore[ply] - positional score for ply ply
  274.  * INCscore    - bonus score or penalty for certain positions
  275.  * slk - single lone king flag
  276.  * Sdepth - search goal depth
  277.  * xwndw - evaluation window about alpha/beta
  278.  * EWNDW - second evaluation window about alpha/beta
  279.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  280.  */
  281. inline
  282. int
  283. ScoreKPK (short int side,
  284.       short int winner,
  285.       short int loser,
  286.       short int king1,
  287.       register short int king2,
  288.       register short int sq)
  289.  
  290. /*
  291.  * Score King and Pawns versus King endings.
  292.  */
  293.  
  294. {
  295.   register short s, r;
  296.  
  297.   s = ((PieceCnt[winner] == 1) ? 50 : 120);
  298.   if (winner == white)
  299.     {
  300.       r = row (sq) - ((side == loser) ? 1 : 0);
  301.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  302.     s += 10 * row (sq);
  303.       else
  304.     s = 500 + 50 * row (sq);
  305.       if (row (sq) < 6)
  306.     sq += 16;
  307.       else if (row (sq) == 6)
  308.     sq += 8;
  309.     }
  310.   else
  311.     {
  312.       r = row (sq) + ((side == loser) ? 1 : 0);
  313.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  314.     s += 10 * (7 - row (sq));
  315.       else
  316.     s = 500 + 50 * (7 - row (sq));
  317.       if (row (sq) > 1)
  318.     sq -= 16;
  319.       else if (row (sq) == 1)
  320.     sq -= 8;
  321.     }
  322.   s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  323.   return (s);
  324. }
  325.  
  326.  
  327. inline
  328. int
  329. ScoreKBNK (short int winner, short int king1, short int king2)
  330.  
  331.  
  332. /*
  333.  * Score King+Bishop+Knight versus King endings. This doesn't work all that
  334.  * well but it's better than nothing.
  335.  */
  336.  
  337. {
  338.   register short s, sq, KBNKsq = 0;
  339.  
  340.   for (sq = 0; sq < 64; sq++)
  341.     if (board[sq] == bishop)
  342.       KBNKsq = (((row (sq) % 2) == (column (sq) % 2)) ? 0 : 7);
  343.  
  344.   s = emtl[winner] - 300;
  345.   s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  346.   s -= ((taxicab (king1, king2) + distance (PieceList[winner][1], king2) + distance (PieceList[winner][2], king2)));
  347.   return (s);
  348. }
  349.  
  350. inline
  351. short int
  352. ScoreLoneKing (short int side)
  353.  
  354. /*
  355.  * Static evaluation when loser has only a king and winner has no pawns or no
  356.  * pieces.
  357.  */
  358.  
  359. {
  360.   register short winner, loser, king1, king2, s, i;
  361.  
  362.   UpdateWeights ();
  363.   winner = ((mtl[white] > mtl[black]) ? white : black);
  364.   loser = winner ^ 1;
  365.   king1 = PieceList[winner][0];
  366.   king2 = PieceList[loser][0];
  367.  
  368.   s = 0;
  369.  
  370.   if (pmtl[winner] > 0)
  371.     for (i = 1; i <= PieceCnt[winner]; i++)
  372.       s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  373.  
  374.   else if (emtl[winner] == valueB + valueN)
  375.     s = ScoreKBNK (winner, king1, king2);
  376.  
  377.   else if (emtl[winner] > valueB)
  378.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  379.  
  380.   return ((side == winner) ? s : -s);
  381. }
  382.  
  383. int
  384. evaluate (register short int side,
  385.       register short int ply,
  386.       register short int alpha,
  387.       register short int beta,
  388.       short int INCscore,
  389.       short int *slk,    /* output single lone king */
  390.       short int *InChk)    /* output Check flag */
  391.  
  392. /*
  393.  * Compute an estimate of the score by adding the positional score from the
  394.  * previous ply to the material difference. If this score falls inside a
  395.  * window which is 180 points wider than the alpha-beta window (or within a
  396.  * 50 point window during quiescence search) call ScorePosition() to
  397.  * determine a score, otherwise return the estimated score. If one side has
  398.  * only a king and the other either has no pawns or no pieces then the
  399.  * function ScoreLoneKing() is called.
  400.  */
  401.  
  402. {
  403.   register short evflag, xside;
  404.   short s;
  405.  
  406.   xside = side ^ 1;
  407.   s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  408.   hung[white] = hung[black] = 0;
  409.   *slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  410.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  411.  
  412.   if (*slk)
  413.     evflag = false;
  414.   else
  415.     /* should we use the estimete or score the position */
  416.     evflag = (ply == 1 ||
  417.           ((ply <= Sdepth)) ||
  418.           ((ply == Sdepth + 1 || ply == (Sdepth + 2)) && (s > (alpha - xwndw) && s < (beta + xwndw))) ||
  419.        (ply > (Sdepth + 2) && s >= (alpha - EWNDW) && s <= (beta + EWNDW)));
  420. #ifdef DEBUG4
  421.   if (debuglevel & 1)
  422.     evflag = true;
  423. #endif
  424.   if (evflag)
  425.     {
  426.       /* score the position */
  427.       ataks (side, atak[side]);
  428.       if (Anyatak (side, PieceList[xside][0]))
  429.     return (10001 - ply);
  430.       ataks (xside, atak[xside]);
  431.       *InChk = Anyatak (xside, PieceList[side][0]);
  432.       EvalNodes++;
  433.       s = ScorePosition (side);
  434.     }
  435.   else
  436.     {
  437.       /* use the estimate but look at check and slk */
  438.       if (SqAtakd (PieceList[xside][0], side))
  439.     return (10001 - ply);
  440.       *InChk = SqAtakd (PieceList[side][0], xside);
  441.       if (*slk)
  442.     s = ScoreLoneKing (side);
  443.     }
  444.  
  445.   Pscore[ply] = s - mtl[side] + mtl[xside];
  446.   ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] : 0);
  447.   return (s);
  448. }
  449.  
  450. inline
  451. void
  452. BRscan (short int sq, register short int *s, short int *mob)
  453.  
  454. /*
  455.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  456.  * hung[] array if a pin is found.
  457.  */
  458. {
  459.   register short u, pin;
  460.   register unsigned char *ppos, *pdir;
  461.   short piece, *Kf;
  462.  
  463.   Kf = Kfield[c1];
  464.   *mob = 0;
  465.   piece = board[sq];
  466.   ppos = nextpos[piece][sq];
  467.   pdir = nextdir[piece][sq];
  468.   u = ppos[sq];
  469.   pin = -1;            /* start new direction */
  470.   do
  471.     {
  472.       *s += Kf[u];
  473.       if (color[u] == neutral)
  474.     {
  475.       (*mob)++;
  476.       if (ppos[u] == pdir[u])
  477.         pin = -1;        /* oops new direction */
  478.       u = ppos[u];
  479.     }
  480.       else if (pin < 0)
  481.     {
  482.       if (board[u] == pawn || board[u] == king)
  483.         u = pdir[u];
  484.       else
  485.         {
  486.           if (ppos[u] != pdir[u])
  487.         pin = u;    /* not on the edge and on to find a pin */
  488.           u = ppos[u];
  489.         }
  490.     }
  491.       else
  492.     {
  493.       if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  494.         {
  495.           if (color[pin] == c2)
  496.         {
  497.           *s += PINVAL;
  498.           if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  499.             ++hung[c2];
  500.         }
  501.           else
  502.         *s += XRAY;
  503.         }
  504.       pin = -1;        /* new direction */
  505.       u = pdir[u];
  506.     }
  507.   } while (u != sq);
  508. }
  509.  
  510. inline
  511. short int
  512. KingScan (register short int sq)
  513.  
  514. /*
  515.  * Assign penalties if king can be threatened by checks, if squares near the
  516.  * king are controlled by the enemy (especially the queen), or if there are
  517.  * no pawns near the king. The following must be true: board[sq] == king c1
  518.  * == color[sq] c2 == otherside[c1]
  519.  */
  520.  
  521. #define ScoreThreat \
  522.     if (color[u] != c2)\
  523.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  524.       else s -= 3
  525.  
  526. {
  527.   register short int s;
  528.   register short u;
  529.   register unsigned char *ppos, *pdir;
  530.   register short cnt, ok;
  531.  
  532.   s = 0;
  533.   cnt = 0;
  534.   if (HasBishop[c2] || HasQueen[c2])
  535.     {
  536.       ppos = nextpos[bishop][sq];
  537.       pdir = nextdir[bishop][sq];
  538.       u = ppos[sq];
  539.       do
  540.     {
  541.       if (atk2[u] & ctlBQ)
  542.         ScoreThreat;
  543.       u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  544.       } while (u != sq);
  545.     }
  546.   if (HasRook[c2] || HasQueen[c2])
  547.     {
  548.       ppos = nextpos[rook][sq];
  549.       pdir = nextdir[rook][sq];
  550.       u = ppos[sq];
  551.       do
  552.     {
  553.       if (atk2[u] & ctlRQ)
  554.         ScoreThreat;
  555.       u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  556.       } while (u != sq);
  557.     }
  558.   if (HasKnight[c2])
  559.     {
  560.       pdir = nextdir[knight][sq];
  561.       u = pdir[sq];
  562.       do
  563.     {
  564.       if (atk2[u] & ctlNN)
  565.         ScoreThreat;
  566.       u = pdir[u];
  567.       } while (u != sq);
  568.     }
  569.   s += (KSFTY * KTHRT[cnt]) / 16;
  570.  
  571.   cnt = 0;
  572.   ok = false;
  573.   pdir = nextpos[king][sq];
  574.   u = pdir[sq];
  575.   do
  576.     {
  577.       if (board[u] == pawn)
  578.     ok = true;
  579.       if (atk2[u] > atk1[u])
  580.     {
  581.       ++cnt;
  582.       if (atk2[u] & ctlQ)
  583.         if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  584.           s -= 4 * KSFTY;
  585.     }
  586.       u = pdir[u];
  587.   } while (u != sq);
  588.   if (!ok)
  589.     s -= KSFTY;
  590.   if (cnt > 1)
  591.     s -= (KSFTY);
  592.   return (s);
  593. }
  594.  
  595. inline
  596. int
  597. trapped (register short int sq)
  598.  
  599. /*
  600.  * See if the attacked piece has unattacked squares to move to. The following
  601.  * must be true: c1 == color[sq] c2 == otherside[c1]
  602.  */
  603.  
  604. {
  605.   register short u, piece;
  606.   register unsigned char *ppos, *pdir;
  607.  
  608.   piece = board[sq];
  609.   ppos = nextpos[ptype[c1][piece]][sq];
  610.   pdir = nextdir[ptype[c1][piece]][sq];
  611.   if (piece == pawn)
  612.     {
  613.       u = ppos[sq];        /* follow no captures thread */
  614.       if (color[u] == neutral)
  615.     {
  616.       if (atk1[u] >= atk2[u])
  617.         return (false);
  618.       if (atk2[u] < ctlP)
  619.         {
  620.           u = ppos[u];
  621.           if (color[u] == neutral && atk1[u] >= atk2[u])
  622.         return (false);
  623.         }
  624.     }
  625.       u = pdir[sq];        /* follow captures thread */
  626.       if (color[u] == c2)
  627.     return (false);
  628.       u = pdir[u];
  629.       if (color[u] == c2)
  630.     return (false);
  631.     }
  632.   else
  633.     {
  634.       u = ppos[sq];
  635.       do
  636.     {
  637.       if (color[u] != c1)
  638.         if (atk2[u] == 0 || board[u] >= piece)
  639.           return (false);
  640.       u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  641.       } while (u != sq);
  642.     }
  643.   return (true);
  644. }
  645.  
  646.  
  647. static inline int
  648. PawnValue(short int sq, short int side)
  649. /*
  650.  * Calculate the positional value for a pawn on 'sq'.
  651.  */
  652.  
  653. {
  654.     register short  j, fyle, rank;
  655.     register short  s, a1, a2, in_square, r, e;
  656.  
  657.     a1 = (atk1[sq] & 0x4FFF);
  658.     a2 = (atk2[sq] & 0x4FFF);
  659.     rank = row(sq);
  660.     fyle = column(sq);
  661.     s = 0;
  662.     if (c1 == white) {
  663.         s = Mwpawn[sq];
  664.         if ((sq == 11 && color[19] != neutral)
  665.             || (sq == 12 && color[20] != neutral))
  666.             s += PEDRNK2B;
  667.         if ((fyle == 0 || PC1[fyle - 1] == 0)
  668.             && (fyle == 7 || PC1[fyle + 1] == 0))
  669.             s += ISOLANI[fyle];
  670.         else if (PC1[fyle] > 1)
  671.             s += PDOUBLED;
  672.         if (a1 < ctlP && atk1[sq + 8] < ctlP) {
  673.             s += BACKWARD[a2 & 0xFF];
  674.             if (PC2[fyle] == 0)
  675.                 s += PWEAKH;
  676.             if (color[sq + 8] != neutral)
  677.                 s += PBLOK;
  678.         }
  679.         if (PC2[fyle] == 0) {
  680.             if (side == black)
  681.                 r = rank - 1;
  682.             else
  683.                 r = rank;
  684.             in_square = (row(bking) >= r && distance(sq, bking) < 8 - r);
  685.             if (a2 == 0 || side == white)
  686.                 e = 0;
  687.             else
  688.                 e = 1;
  689.             for (j = sq + 8; j < 64; j += 8)
  690.                 if (atk2[j] >= ctlP) {
  691.                     e = 2;
  692.                     break;
  693.                 } else if (atk2[j] > 0 || color[j] != neutral)
  694.                     e = 1;
  695.             if (e == 2)
  696.                 s += (stage * PassedPawn3[rank]) / 10;
  697.             else if (in_square || e == 1)
  698.                 s += (stage * PassedPawn2[rank]) / 10;
  699.             else if (emtl[black] > 0)
  700.                 s += (stage * PassedPawn1[rank]) / 10;
  701.             else
  702.                 s += PassedPawn0[rank];
  703.         }
  704.     } else if (c1 == black) {
  705.         s = Mbpawn[sq];
  706.         if ((sq == 51 && color[43] != neutral)
  707.             || (sq == 52 && color[44] != neutral))
  708.             s += PEDRNK2B;
  709.         if ((fyle == 0 || PC1[fyle - 1] == 0) &&
  710.             (fyle == 7 || PC1[fyle + 1] == 0))
  711.             s += ISOLANI[fyle];
  712.         else if (PC1[fyle] > 1)
  713.             s += PDOUBLED;
  714.         if (a1 < ctlP && atk1[sq - 8] < ctlP) {
  715.             s += BACKWARD[a2 & 0xFF];
  716.             if (PC2[fyle] == 0)
  717.                 s += PWEAKH;
  718.             if (color[sq - 8] != neutral)
  719.                 s += PBLOK;
  720.         }
  721.         if (PC2[fyle] == 0) {
  722.             if (side == white)
  723.                 r = rank + 1;
  724.             else
  725.                 r = rank;
  726.             in_square = (row(wking) <= r && distance(sq, wking) < r + 1);
  727.             if (a2 == 0 || side == black)
  728.                 e = 0;
  729.             else
  730.                 e = 1;
  731.             for (j = sq - 8; j >= 0; j -= 8)
  732.                 if (atk2[j] >= ctlP) {
  733.                     e = 2;
  734.                     break;
  735.                 } else if (atk2[j] > 0 || color[j] != neutral)
  736.                     e = 1;
  737.             if (e == 2)
  738.                 s += (stage * PassedPawn3[7 - rank]) / 10;
  739.             else if (in_square || e == 1)
  740.                 s += (stage * PassedPawn2[7 - rank]) / 10;
  741.             else if (emtl[white] > 0)
  742.                 s += (stage * PassedPawn1[7 - rank]) / 10;
  743.             else
  744.                 s += PassedPawn0[7 - rank];
  745.         }
  746.     }
  747.     if (a2 > 0) {
  748.         if (a1 == 0 || a2 > ctlP + 1) {
  749.             s += HUNGP;
  750.             ++hung[c1];
  751.             if (trapped(sq))
  752.                 ++hung[c1];
  753.         } else if (a2 > a1)
  754.             s += ATAKD;
  755.     }
  756.     return (s);
  757. }
  758. inline
  759. int
  760. KnightValue (short int sq, short int side)
  761.  
  762. /*
  763.  * Calculate the positional value for a knight on 'sq'.
  764.  */
  765.  
  766. {
  767.   register short s, a2, a1;
  768.  
  769.   s = Mknight[c1][sq];
  770.   a2 = (atk2[sq] & 0x4FFF);
  771.   if (a2 > 0)
  772.     {
  773.       a1 = (atk1[sq] & 0x4FFF);
  774.       if (a1 == 0 || a2 > ctlBN + 1)
  775.     {
  776.       s += HUNGP;
  777.       ++hung[c1];
  778.       if (trapped (sq))
  779.         ++hung[c1];
  780.     }
  781.       else if (a2 >= ctlBN || a1 < ctlP)
  782.     s += ATAKD;
  783.     }
  784.   return (s);
  785. }
  786.  
  787. inline
  788. int
  789. BishopValue (short int sq, short int side)
  790.  
  791. /*
  792.  * Calculate the positional value for a bishop on 'sq'.
  793.  */
  794.  
  795. {
  796.   register short a2, a1;
  797.   short s, mob;
  798.  
  799.   s = Mbishop[c1][sq];
  800.   BRscan (sq, &s, &mob);
  801.   s += BMBLTY[mob];
  802.   a2 = (atk2[sq] & 0x4FFF);
  803.   if (a2 > 0)
  804.     {
  805.       a1 = (atk1[sq] & 0x4FFF);
  806.       if (a1 == 0 || a2 > ctlBN + 1)
  807.     {
  808.       s += HUNGP;
  809.       ++hung[c1];
  810.       if (trapped (sq))
  811.         ++hung[c1];
  812.     }
  813.       else if (a2 >= ctlBN || a1 < ctlP)
  814.     s += ATAKD;
  815.     }
  816.   return (s);
  817. }
  818.  
  819. inline
  820. int
  821. RookValue (register short int sq, short int side)
  822.  
  823. /*
  824.  * Calculate the positional value for a rook on 'sq'.
  825.  */
  826.  
  827. {
  828.   register short fyle, a2, a1;
  829.   short s, mob;
  830.  
  831.   s = RookBonus;
  832.   BRscan (sq, &s, &mob);
  833.   s += RMBLTY[mob];
  834.   fyle = column (sq);
  835.   if (PC1[fyle] == 0)
  836.     s += RHOPN;
  837.   if (PC2[fyle] == 0)
  838.     s += RHOPNX;
  839.   if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  840.     s += 10;
  841.   if (stage > 2)
  842.     s += 14 - taxicab (sq, EnemyKing);
  843.   a2 = (atk2[sq] & 0x4FFF);
  844.   if (a2 > 0)
  845.     {
  846.       a1 = (atk1[sq] & 0x4FFF);
  847.       if (a1 == 0 || a2 > ctlR + 1)
  848.     {
  849.       s += HUNGP;
  850.       ++hung[c1];
  851.  
  852.       if (trapped (sq))
  853.         ++hung[c1];
  854.     }
  855.       else if (a2 >= ctlR || a1 < ctlP)
  856.     s += ATAKD;
  857.     }
  858.   return (s);
  859. }
  860.  
  861. inline
  862. int
  863. QueenValue (register short int sq, short int side)
  864.  
  865. /*
  866.  * Calculate the positional value for a queen on 'sq'.
  867.  */
  868.  
  869. {
  870.   register short s, a2, a1;
  871.  
  872.   s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  873.   if (stage > 2)
  874.     s += 14 - taxicab (sq, EnemyKing);
  875.   a2 = (atk2[sq] & 0x4FFF);
  876.   if (a2 > 0)
  877.     {
  878.       a1 = (atk1[sq] & 0x4FFF);
  879.       if (a1 == 0 || a2 > ctlQ + 1)
  880.     {
  881.       s += HUNGP;
  882.       ++hung[c1];
  883.       if (trapped (sq))
  884.         ++hung[c1];
  885.     }
  886.       else if (a2 >= ctlQ || a1 < ctlP)
  887.     s += ATAKD;
  888.     }
  889.   return (s);
  890. }
  891.  
  892. inline
  893. int
  894. KingValue (short int sq, short int side)
  895.  
  896. /*
  897.  * Calculate the positional value for a king on 'sq'.
  898.  */
  899.  
  900. {
  901.   register short fyle, a2, a1;
  902.   short s;
  903.   s = (emtl[side ^ 1] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  904.   if (KSFTY > 0)
  905.     if (Developed[c2] || stage > 0)
  906.       s += KingScan (sq);
  907.   if (castld[c1])
  908.     s += KCASTLD;
  909.   else if (Mvboard[kingP[c1]])
  910.     s += KMOVD;
  911.  
  912.   fyle = column (sq);
  913.   if (PC1[fyle] == 0)
  914.     s += KHOPN;
  915.   if (PC2[fyle] == 0)
  916.     s += KHOPNX;
  917.   switch (fyle)
  918.     {
  919.     case 5:
  920.       if (PC1[7] == 0)
  921.     s += KHOPN;
  922.       if (PC2[7] == 0)
  923.     s += KHOPNX;
  924.       /* Fall through */
  925.     case 4:
  926.     case 6:
  927.     case 0:
  928.       if (PC1[fyle + 1] == 0)
  929.     s += KHOPN;
  930.       if (PC2[fyle + 1] == 0)
  931.     s += KHOPNX;
  932.       break;
  933.     case 2:
  934.       if (PC1[0] == 0)
  935.     s += KHOPN;
  936.       if (PC2[0] == 0)
  937.     s += KHOPNX;
  938.       /* Fall through */
  939.     case 3:
  940.     case 1:
  941.     case 7:
  942.       if (PC1[fyle - 1] == 0)
  943.     s += KHOPN;
  944.       if (PC2[fyle - 1] == 0)
  945.     s += KHOPNX;
  946.       break;
  947.     default:
  948.       /* Impossible! */
  949.       break;
  950.     }
  951.  
  952.   a2 = (atk2[sq] & 0x4FFF);
  953.   if (a2 > 0)
  954.     {
  955.       a1 = (atk1[sq] & 0x4FFF);
  956.       if (a1 == 0 || a2 > ctlK + 1)
  957.     {
  958.       s += HUNGP;
  959.       ++hung[c1];
  960.     }
  961.       else
  962.     s += ATAKD;
  963.     }
  964.   return (s);
  965. }
  966.  
  967. #if !defined NOSCORESPACE
  968. inline
  969. void
  970. ScoreSpace (void)
  971. {
  972.   register short *b, *w, *sw, *sb;
  973.   register short sBl, sWh;
  974.   sBl = sWh = 0;
  975.   for (b = &atak[black][63], w = &atak[white][63], sw = &SpaceBonusW[63], sb = &SpaceBonusB[63];
  976.        sw > &SpaceBonusW[0];
  977.        b--, w--, sw--, sb--)
  978.     {
  979.       if (*b > *w)
  980.     {
  981.       if (*b > ctlR)
  982.         sBl += *sb;
  983.     }
  984.       else if (*b < *w)
  985.     if (*w > ctlR)
  986.       sWh += *sw;
  987.     }
  988.   pscore[white] += (sWh);
  989.   pscore[black] += (sBl);
  990.   sscore[white] = sWh;
  991.   sscore[black] = sBl;
  992. }
  993.  
  994. #endif
  995.  
  996.  
  997.  
  998. short int
  999. ScorePosition (register short int side)
  1000.  
  1001. /*
  1002.  * Perform normal static evaluation of board position. A score is generated
  1003.  * for each piece and these are summed to get a score for each side.
  1004.  */
  1005.  
  1006. {
  1007.   register short int score;
  1008.   register short sq, s, i, xside;
  1009.  
  1010.   UpdateWeights ();
  1011.   xside = side ^ 1;
  1012.   hung[white]= hung[black] = pscore[white] = pscore[black] = 0;
  1013. #if !defined NOSCORESPACE
  1014.   if (stage < SCORESPLIM)
  1015.     ScoreSpace ();
  1016. #endif
  1017.   for (c1 = white; c1 <= black; c1++)
  1018.     {
  1019.       c2 = c1 ^ 1;
  1020.       /* atk1 is array of atacks on squares by my side */
  1021.       atk1 = atak[c1];
  1022.       /* atk2 is array of atacks on squares by other side */
  1023.       atk2 = atak[c2];
  1024.       /* same for PC1 and PC2 */
  1025.       PC1 = PawnCnt[c1];
  1026.       PC2 = PawnCnt[c2];
  1027.       for (i = PieceCnt[c1]; i >= 0; i--)
  1028.     {
  1029.       sq = PieceList[c1][i];
  1030.       switch (board[sq])
  1031.         {
  1032.         case pawn:
  1033.           s = PawnValue (sq, side);
  1034.           break;
  1035.         case knight:
  1036.           s = KnightValue (sq, side);
  1037.           break;
  1038.         case bishop:
  1039.           s = BishopValue (sq, side);
  1040.           break;
  1041.         case rook:
  1042.           s = RookValue (sq, side);
  1043.           break;
  1044.         case queen:
  1045.           s = QueenValue (sq, side);
  1046.           break;
  1047.         case king:
  1048.           s = KingValue (sq, side);
  1049.           break;
  1050.         default:
  1051.           s = 0;
  1052.           break;
  1053.         }
  1054.       pscore[c1] += s;
  1055.       svalue[sq] = s;
  1056.     }
  1057.     }
  1058.   if (hung[side] > 1)
  1059.     pscore[side] += HUNGX;
  1060.   if (hung[xside] > 1)
  1061.     pscore[xside] += HUNGX;
  1062.  
  1063.   score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  1064.   if (dither)
  1065.     {
  1066.       if (flag.hash)
  1067.     srand (starttime + (unsigned int) hashbd);
  1068.       score += urand () % dither;
  1069.     }
  1070.  
  1071.   if (score > 0 && pmtl[side] == 0)
  1072.     if (emtl[side] < valueR)
  1073.       score = 0;
  1074.     else if (score < valueR)
  1075.       score /= 2;
  1076.   if (score < 0 && pmtl[xside] == 0)
  1077.     if (emtl[xside] < valueR)
  1078.       score = 0;
  1079.     else if (-score < valueR)
  1080.       score /= 2;
  1081.  
  1082.   if (mtl[xside] == valueK && emtl[side] > valueB)
  1083.     score += 200;
  1084.   if (mtl[side] == valueK && emtl[xside] > valueB)
  1085.     score -= 200;
  1086.   return (score);
  1087. }
  1088. static inline void
  1089. BlendBoard (const short int a[64], const short int b[64], short int c[64])
  1090. {
  1091.   register int sq, s;
  1092.   s = 10 - stage;
  1093.   for (sq = 0; sq < 64; sq++)
  1094.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  1095. }
  1096.  
  1097.  
  1098. static inline void
  1099. CopyBoard (const short int a[64], short int b[64])
  1100. {
  1101.   register short *sqa, *sqb;
  1102.   for (sqa = a, sqb = b; sqa < a + 64;)
  1103.     *sqb++ = *sqa++;
  1104. }
  1105.  
  1106.  
  1107. void
  1108. ExaminePosition (void)
  1109.  
  1110. /*
  1111.  * This is done one time before the search is started. Set up arrays Mwpawn,
  1112.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  1113.  * to determine the positional value of each piece.
  1114.  */
  1115.  
  1116. {
  1117.   register short i, sq;
  1118.   short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, fyle,
  1119.    rank;
  1120.   static short PawnStorm = false;
  1121.  
  1122.   ataks (white, atak[white]);
  1123.   ataks (black, atak[black]);
  1124.   UpdateWeights ();
  1125.   HasKnight[white] = HasKnight[black] = 0;
  1126.   HasBishop[white] = HasBishop[black] = 0;
  1127.   HasRook[white] = HasRook[black] = 0;
  1128.   HasQueen[white] = HasQueen[black] = 0;
  1129.   for (side = white; side <= black; side++)
  1130.     for (i = PieceCnt[side]; i >= 0; i--)
  1131.       switch (board[PieceList[side][i]])
  1132.     {
  1133.     case knight:
  1134.       ++HasKnight[side];
  1135.       break;
  1136.     case bishop:
  1137.       ++HasBishop[side];
  1138.       break;
  1139.     case rook:
  1140.       ++HasRook[side];
  1141.       break;
  1142.     case queen:
  1143.       ++HasQueen[side];
  1144.       break;
  1145.     }
  1146.   if (!Developed[white])
  1147.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  1148.             board[5] != bishop && board[6] != knight);
  1149.   if (!Developed[black])
  1150.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  1151.             board[61] != bishop && board[62] != knight);
  1152.   if (!PawnStorm && stage < 5)
  1153.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  1154.          (column (wking) > 4 && column (bking) < 3));
  1155.  
  1156.   CopyBoard (pknight, Mknight[white]);
  1157.   CopyBoard (pknight, Mknight[black]);
  1158.   CopyBoard (pbishop, Mbishop[white]);
  1159.   CopyBoard (pbishop, Mbishop[black]);
  1160.   BlendBoard (KingOpening, KingEnding, Mking[white]);
  1161.   BlendBoard (KingOpening, KingEnding, Mking[black]);
  1162.  
  1163.   for (sq = 0; sq < 64; sq++)
  1164.     {
  1165.       fyle = column (sq);
  1166.       rank = row (sq);
  1167.       wstrong = bstrong = true;
  1168.       for (i = sq; i < 64; i += 8)
  1169.     if (Patak (black, i))
  1170.       {
  1171.         wstrong = false;
  1172.         break;
  1173.       }
  1174.       for (i = sq; i >= 0; i -= 8)
  1175.     if (Patak (white, i))
  1176.       {
  1177.         bstrong = false;
  1178.         break;
  1179.       }
  1180.       wpadv = bpadv = PADVNCM;
  1181.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0))
  1182.     wpadv = PADVNCI;
  1183.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0))
  1184.     bpadv = PADVNCI;
  1185.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  1186.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  1187.       Mwpawn[sq] += PawnBonus;
  1188.       Mbpawn[sq] += PawnBonus;
  1189.       if (Mvboard[kingP[white]])
  1190.     {
  1191.       if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  1192.         Mwpawn[sq] += PAWNSHIELD;
  1193.     }
  1194.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  1195.     Mwpawn[sq] += PAWNSHIELD / 2;
  1196.       if (Mvboard[kingP[black]])
  1197.     {
  1198.       if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  1199.         Mbpawn[sq] += PAWNSHIELD;
  1200.     }
  1201.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  1202.     Mbpawn[sq] += PAWNSHIELD / 2;
  1203.       if (PawnStorm)
  1204.     {
  1205.       if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  1206.         Mwpawn[sq] += 3 * rank - 21;
  1207.       if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  1208.         Mbpawn[sq] -= 3 * rank;
  1209.     }
  1210.       Mknight[white][sq] += 5 - distance (sq, bking);
  1211.       Mknight[white][sq] += 5 - distance (sq, wking);
  1212.       Mknight[black][sq] += 5 - distance (sq, wking);
  1213.       Mknight[black][sq] += 5 - distance (sq, bking);
  1214.       Mbishop[white][sq] += BishopBonus;
  1215.       Mbishop[black][sq] += BishopBonus;
  1216.       for (i = PieceCnt[black]; i >= 0; i--)
  1217.     if (distance (sq, PieceList[black][i]) < 3)
  1218.       Mknight[white][sq] += KNIGHTPOST;
  1219.       for (i = PieceCnt[white]; i >= 0; i--)
  1220.     if (distance (sq, PieceList[white][i]) < 3)
  1221.       Mknight[black][sq] += KNIGHTPOST;
  1222.       if (wstrong)
  1223.     Mknight[white][sq] += KNIGHTSTRONG;
  1224.       if (bstrong)
  1225.     Mknight[black][sq] += KNIGHTSTRONG;
  1226.       if (wstrong)
  1227.     Mbishop[white][sq] += BISHOPSTRONG;
  1228.       if (bstrong)
  1229.     Mbishop[black][sq] += BISHOPSTRONG;
  1230.  
  1231.       if (HasBishop[white] == 2)
  1232.     Mbishop[white][sq] += 8;
  1233.       if (HasBishop[black] == 2)
  1234.     Mbishop[black][sq] += 8;
  1235.       if (HasKnight[white] == 2)
  1236.     Mknight[white][sq] += 5;
  1237.       if (HasKnight[black] == 2)
  1238.     Mknight[black][sq] += 5;
  1239.  
  1240.       Kfield[white][sq] = Kfield[black][sq] = 0;
  1241.       if (distance (sq, wking) == 1)
  1242.     Kfield[black][sq] = KATAK;
  1243.       if (distance (sq, bking) == 1)
  1244.     Kfield[white][sq] = KATAK;
  1245.       Pd = 0;
  1246.       for (k = 0; k <= PieceCnt[white]; k++)
  1247.     {
  1248.       i = PieceList[white][k];
  1249.       if (board[i] == pawn)
  1250.         {
  1251.           pp = true;
  1252.           z = i + ((row (i) == 6) ? 8 : 16);
  1253.           for (j = i + 8; j < 64; j += 8)
  1254.         if (Patak (black, j) || board[j] == pawn)
  1255.           {
  1256.             pp = false;
  1257.             break;
  1258.           }
  1259.           Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1260.         }
  1261.     }
  1262.       for (k = 0; k <= PieceCnt[black]; k++)
  1263.     {
  1264.       i = PieceList[black][k];
  1265.       if (board[i] == pawn)
  1266.         {
  1267.           pp = true;
  1268.           z = i - ((row (i) == 1) ? 8 : 16);
  1269.           for (j = i - 8; j >= 0; j -= 8)
  1270.         if (Patak (white, j) || board[j] == pawn)
  1271.           {
  1272.             pp = false;
  1273.             break;
  1274.           }
  1275.           Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1276.         }
  1277.     }
  1278.       if (Pd != 0)
  1279.     {
  1280.       val = (Pd * stage2) / 10;
  1281.       Mking[white][sq] -= val;
  1282.       Mking[black][sq] -= val;
  1283.     }
  1284.     }
  1285. }
  1286.  
  1287. void
  1288. UpdateWeights (void)
  1289.  
  1290. /*
  1291.  * If material balance has changed, determine the values for the positional
  1292.  * evaluation terms.
  1293.  */
  1294.  
  1295. {
  1296.   register short s1;
  1297.  
  1298.   emtl[white] = mtl[white] - pmtl[white] - valueK;
  1299.   emtl[black] = mtl[black] - pmtl[black] - valueK;
  1300.   tmtl = emtl[white] + emtl[black];
  1301.   s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  1302.   if (s1 != stage)
  1303.     {
  1304.       stage = s1;
  1305.       stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  1306.       PEDRNK2B = -15;        /* centre pawn on 2nd rank & blocked */
  1307.       PBLOK = -4;        /* blocked backward pawn */
  1308.       PDOUBLED = -14;        /* doubled pawn */
  1309.       PWEAKH = -4;        /* weak pawn on half open file */
  1310.       PAWNSHIELD = 10 - stage;    /* pawn near friendly king */
  1311.       PADVNCM = 10;        /* advanced pawn multiplier */
  1312.       PADVNCI = 7;        /* muliplier for isolated pawn */
  1313.       PawnBonus = stage;
  1314.  
  1315.       KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  1316.       KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1317.  
  1318.       BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1319.       BishopBonus = BBONUS * stage;
  1320.  
  1321.       RHOPN = 10;        /* rook on half open file */
  1322.       RHOPNX = 4;
  1323.       RookBonus = RBONUS * stage;
  1324.  
  1325.       XRAY = 8;            /* Xray attack on piece */
  1326.       PINVAL = 10;        /* Pin */
  1327.  
  1328.       KHOPN = (3 * stage - 30) / 2;    /* king on half open file */
  1329.       KHOPNX = KHOPN / 2;
  1330.       KCASTLD = 10 - stage;
  1331.       KMOVD = -40 / (stage + 1);/* king moved before castling */
  1332.       KATAK = (10 - stage) / 2;    /* B,R attacks near enemy king */
  1333.       KSFTY = ((stage < 8) ? KINGSAFETY - 2 * stage : 0);
  1334.  
  1335.       ATAKD = -6;        /* defender > attacker */
  1336.       HUNGP = -12;        /* each hung piece */
  1337.       HUNGX = -18;        /* extra for >1 hung piece */
  1338.     }
  1339. }
  1340.